<script setup lang="ts">
import { useI18n } from 'vue-i18n';
import Motion from './utils/motion';
import { loginRules } from './utils/rule';
import { useNav } from '@/layout/hooks/useNav';
import type { FormInstance } from 'element-plus';
import { $t, transformI18n } from '@/plugins/i18n';
import { useLayout } from '@/layout/hooks/useLayout';
import { useUserStoreHook } from '@/store/modules/user';
import { bg, avatar, illustration } from './utils/static';
import { useRenderIcon } from '@/components/ReIcon/src/hooks';
import { ref, reactive, toRaw, onMounted, onBeforeUnmount } from 'vue';
import { LoginParam } from '@/api/user';
import Lock from '@iconify-icons/ri/lock-fill';
import User from '@iconify-icons/ri/user-3-fill';
import { ElMessage } from 'element-plus';
defineOptions({
  name: 'Login',
});
const loading = ref(false);
const ruleFormRef = ref<FormInstance>();

const { initStorage } = useLayout();
initStorage();

const { t } = useI18n();

const { title } = useNav();

const ruleForm = reactive<LoginParam>({
  username: '',
  password: '',
  isRemember: true,
});

const onLogin = async (formEl: FormInstance | undefined) => {
  loading.value = true;
  if (!formEl) return;
  await formEl.validate((valid, fields) => {
    if (valid) {
      useUserStoreHook()
        .login(ruleForm)
        .then(res => {
          console.log(res);
          ElMessage.success('login successfully!');
        })
        .catch(err => {
          ElMessage.error(err?.error_description || err.message);
        });
    } else {
      loading.value = false;
      return fields;
    }
  });
};

/** 使用公共函数，避免`removeEventListener`失效 */
function onkeypress({ code }: KeyboardEvent) {
  if (code === 'Enter') {
    onLogin(ruleFormRef.value);
  }
}

onMounted(() => {
  window.document.addEventListener('keypress', onkeypress);
});

onBeforeUnmount(() => {
  window.document.removeEventListener('keypress', onkeypress);
});
</script>

<template>
  <div class="select-none">
    <img :src="bg" class="wave" />
    <div class="login-container">
      <div class="img">
        <component :is="toRaw(illustration)" />
      </div>
      <div class="login-box">
        <div class="login-form">
          <avatar class="avatar" />
          <Motion>
            <h2 class="outline-none">{{ title }}</h2>
          </Motion>

          <el-form ref="ruleFormRef" :model="ruleForm" :rules="loginRules" size="large">
            <Motion :delay="100">
              <el-form-item
                :rules="[
                  {
                    required: true,
                    message: transformI18n($t('login.usernameReg')),
                    trigger: 'blur',
                  },
                ]"
                prop="username"
              >
                <el-input clearable v-model="ruleForm.username" :placeholder="t('login.username')" :prefix-icon="useRenderIcon(User)" />
              </el-form-item>
            </Motion>

            <Motion :delay="150">
              <el-form-item prop="password">
                <el-input clearable show-password v-model="ruleForm.password" :placeholder="t('login.password')" :prefix-icon="useRenderIcon(Lock)" />
              </el-form-item>
            </Motion>
            <Motion :delay="200">
              <div class="text-xs flex justify-start">
                <el-checkbox v-model="ruleForm.isRemember" label="Automatically log me in." size="large" />
              </div>
            </Motion>
            <Motion :delay="250">
              <el-button class="w-full mt-4" size="default" type="primary" :loading="loading" @click="onLogin(ruleFormRef)">
                {{ t('login.login') }}
              </el-button>
            </Motion>
          </el-form>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
@import url('@/style/login.css');
</style>

<style lang="scss" scoped>
:deep(.el-input-group__append, .el-input-group__prepend) {
  padding: 0;
}

.translation {
  ::v-deep(.el-dropdown-menu__item) {
    padding: 5px 40px;
  }

  .check-zh {
    position: absolute;
    left: 20px;
  }

  .check-en {
    position: absolute;
    left: 20px;
  }
}
</style>
